package com.jprocms.module.cms.controller.directive;

import com.jpro.framework.common.pojo.PageResult;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.jprocms.module.cms.controller.admin.guestbook.vo.GuestbookPageReqVO;
import com.jprocms.module.cms.controller.admin.guestbook.vo.GuestbookQueryListReqVO;
import com.jprocms.module.cms.dal.dataobject.guestbook.GuestbookDO;
import com.jprocms.module.cms.enums.EnumGuestbookStatus;
import com.jprocms.module.cms.service.guestbook.GuestbookService;
import com.jprocms.module.cms.util.Freemarkers;
import com.jprocms.module.cms.util.FrontContextUtil;
import com.jprocms.module.cms.web.Directives;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.jprocms.module.cms.web.Directives.*;


/**
 * 留言板列表 标签
 *
 * @author jprocms
 */
public class GuestbookListDirective implements TemplateDirectiveModel {
    /**
     * 站点ID。整型(Long)。
     */
    public static final String SITE_ID = "siteId";
    /**
     * 类型。整型(Integer)。
     */
    public static final String TYPE = "type";
    /**
     * 是否推荐 1 0
     */
    public static final String IS_RECOMMENDED = "isRecommended";
    /**
     * 是否回复。1 0
     */
    public static final String IS_REPLIED = "isReplied";
    /**
     * 是否获取所有站点的数据。布尔型(Boolean)。默认：false。
     */
    public static final String IS_ALL = "isAll";
    /**
     * 状态。
     */
    public static final String STATUS = "status";
    /**
     * 公开。
     */
    public static final String OPEN = "open";

    public static void assemble(GuestbookPageReqVO args, Map<String, ?> params, Long defaultSiteId) {
        Long siteId = getLong(params, SITE_ID);
        // 不获取所有站点，则给默认站点ID
        if (siteId == null && !getBoolean(params, IS_ALL, false)) {
            siteId = defaultSiteId;
        }
        args.setSiteId(siteId);
        Optional.ofNullable(Directives.getInteger(params, TYPE)).ifPresent(args::setGuestbookType);
        Optional.ofNullable(getInteger(params, IS_RECOMMENDED)).ifPresent(args::setRecommended);
        Optional.ofNullable(getInteger(params, IS_REPLIED)).ifPresent(args::setIsReplied);
        Optional.ofNullable(Directives.getInteger(params, STATUS)).ifPresent(args::setStatus);
        //默认查的是已审核通过的列表，是否公开都会查，只需要公开的需要标签限定
        if (args.getStatus() == null) {
            args.setStatus(EnumGuestbookStatus.CHECKED.getStatus());
        }
        Optional.ofNullable(Directives.getInteger(params, OPEN)).ifPresent(args::setIsOpen);
    }

    protected void doExecute(Environment env, Map<String, TemplateModel> params, TemplateModel[] loopVars,
                             TemplateDirectiveBody body, boolean isPage) throws TemplateException, IOException {
        Freemarkers.requireLoopVars(loopVars);
        Freemarkers.requireBody(body);
        GuestbookQueryListReqVO args = new GuestbookQueryListReqVO();
        assemble(args, params, FrontContextUtil.getSiteId(env));
        if (isPage) {
            int page = Directives.getPage(params, env);
            int pageSize = Directives.getPageSize(params, env);
            args.setPageSize(pageSize);
            args.setPageNo(page);
            //默认回复时间降序，ID降序排序
            Collection<OrderItem> orderItems = getOrderItems(params, "reply_date_desc,id_desc");
            args.setOrderItems(orderItems);
            final PageResult<GuestbookDO> guestbookPage = service.getGuestbookPage(args);
            Directives.setTotalPages(guestbookPage.getTotalPages());
            loopVars[0] = env.getObjectWrapper().wrap(guestbookPage);
        } else {
            int offset = Directives.getOffset(params);
            int limit = Directives.getCount(params);
            args.setCount(limit);
            args.setOffset(offset);
            //默认回复时间降序，ID降序排序
            Collection<OrderItem> orderItems = getOrderItems(params, "reply_date_desc,id_desc");
            args.setOrderItems(orderItems);
            List<GuestbookDO> list = service.getGuestbookList(args);
            loopVars[0] = env.getObjectWrapper().wrap(list);
        }
        body.render(env.getOut());
    }

    @SuppressWarnings("unchecked")
    @Override
    public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
            throws TemplateException, IOException {
        doExecute(env, params, loopVars, body, false);
    }

    private final GuestbookService service;

    public GuestbookListDirective(GuestbookService service) {
        this.service = service;
    }
}
